////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
// Copyright (c) 2017 Qualcomm Technologies, Inc.
// All Rights Reserved.
// Confidential and Proprietary - Qualcomm Technologies, Inc.
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @file  camxifecamif.h
/// @brief camxifecamif class declarations
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

#ifndef CAMXIFECAMIF_H
#define CAMXIFECAMIF_H
#include "camxispiqmodule.h"
#include "camxsensorproperty.h"

CAMX_NAMESPACE_BEGIN

/// @brief IFE CAMIF Module Dependence Data
struct IFECAMIFDependence
{
    FLOAT       digitalGain;  ///< Digital Gain Setting From Sensor
    PixelFormat sensorFormat; ///< Sensor Format
};

CAMX_BEGIN_PACKED
/// @brief IFE CAMIF Module Register Set 1
struct IFECAMIFRegCmd1
{
    IFE_IFE_0_VFE_CAMIF_CMD statusRegister; ///< CAMIF Status Register 0x478
    IFE_IFE_0_VFE_CAMIF_CFG configRegister; ///< CAMIF Config Register 0x47c
} CAMX_PACKED;

/// @brief IFE CAMIF Module Register Set 2
struct IFECAMIFRegCmd2
{
    IFE_IFE_0_VFE_CAMIF_LINE_SKIP_PATTERN  lineSkipPatternRegister;  ///< CAMIF Line Skip Pattern Register 0x488
    IFE_IFE_0_VFE_CAMIF_PIXEL_SKIP_PATTERN pixelSkipPatternRegister; ///< pixel skip Pattern Register 0x48c
    IFE_IFE_0_VFE_CAMIF_SKIP_PERIOD        skipPeriodRegister;       ///< CAMIF Skip Period Register 0x490
} CAMX_PACKED;

/// @brief IFE CAMIF Module Register Set 3
struct IFECAMIFRegCmd3
{
    IFE_IFE_0_VFE_CAMIF_IRQ_SUBSAMPLE_PATTERN irqSubsamplePattern; ///< IRQ Subsample Pattern Register 0x49c
    IFE_IFE_0_VFE_CAMIF_EPOCH_IRQ             irqEpochRegister;    ///< Define When the EPOCH IRQ should happen 0x4a0
} CAMX_PACKED;

/// @brief IFE CAMIF Module Register Set 4
struct IFECAMIFRegCmd4
{
    IFE_IFE_0_VFE_CAMIF_RAW_CROP_WIDTH_CFG    rawCropWidthConfig;  ///< Raw Image Width Crop Register 0xce4
    IFE_IFE_0_VFE_CAMIF_RAW_CROP_HEIGHT_CFG   rawCropHeightConfig; ///< Raw Image Height Crop Register 0xce8
} CAMX_PACKED;

CAMX_END_PACKED

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
/// @brief Class for IFE CAMIF Module
////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
class IFECAMIF final : public ISPIQModule
{
public:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Create
    ///
    /// @brief  Create IFECAMIF Object
    ///
    /// @param  pCreateData Pointer to data for CAMIF Creation
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    static CamxResult Create(
        IFEModuleCreateData* pCreateData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// Execute
    ///
    /// @brief  Generate Settings for CAMIF Object
    ///
    /// @param  pInputData Pointer to the Inputdata
    ///
    /// @return CamxResultSuccess if successful.
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual CamxResult Execute(
        ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetRegCmd
    ///
    /// @brief  Retrieve the buffer of the register value
    ///
    /// @return Pointer of the register buffer
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID* GetRegCmd();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// GetDualIFEData
    ///
    /// @brief  Provides information on how dual IFE mode affects the IQ module
    ///
    /// @param  pDualIFEData Pointer to dual IFE data the module will fill in
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual VOID GetDualIFEData(
        IQModuleDualIFEData* pDualIFEData)
    {
        CAMX_ASSERT(NULL != pDualIFEData);

        pDualIFEData->dualIFESensitive = TRUE;
    }

protected:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ~IFECAMIF
    ///
    /// @brief  Destructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    virtual ~IFECAMIF();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// IFECAMIF
    ///
    /// @brief  Constructor
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    IFECAMIF();

private:
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CheckDependenceChange
    ///
    /// @brief  Check if the Dependence Data has changed
    ///
    /// @param  pInputData Point to the Input Data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    BOOL CheckDependenceChange(
        ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// RunCalculation
    ///
    /// @brief  Perform the Interpolation and Calculation
    ///
    /// @param  pInputData Point to the Input Data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult RunCalculation(
        ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// CreateCmdList
    ///
    /// @brief  Generate the Command List
    ///
    /// @param  pInputData Point to the Input Data
    ///
    /// @return CamxResultSuccess if successful
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    CamxResult CreateCmdList(
        ISPInputData* pInputData);

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// ModuleInitialize
    ///
    /// @brief  Initialize the Module Data
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID ModuleInitialize();

    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    /// SetupInitialConfig
    ///
    /// @brief  Configure some of the register value based on the chromatix and image format
    ///
    /// @return None
    ////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    VOID SetupInitialConfig();

    IFECAMIFDependence m_dependenceData; ///< Dependence Data for this module
    IFECAMIFRegCmd1    m_regCmd1;        ///< Register List 1 of this module
    IFECAMIFRegCmd2    m_regCmd2;        ///< Register List 2 of this module
    IFECAMIFRegCmd3    m_regCmd3;        ///< Register List 3 of this module
    IFECAMIFRegCmd4    m_regCmd4;        ///< Register List 4 of this module

    IFECAMIF(const IFECAMIF&)            = delete;    ///< Disallow the copy constructor
    IFECAMIF& operator=(const IFECAMIF&) = delete;    ///< Disallow assignment operator

};

CAMX_NAMESPACE_END

#endif // CAMXIFECAMIF_H
